<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- base href="http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html" --></head><body><div style="background:#fff;border:1px solid #999;margin:-1px -1px 0;padding:0;"><div style="background:#ddd;border:1px solid #999;color:#000;font:13px arial,sans-serif;font-weight:normal;margin:12px;padding:8px;text-align:left">Esta es la versión en caché de <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html" style="text-decoration: underline; color: rgb(0, 0, 204);">http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html</a>
 de Google. Se trata de una captura de pantalla de la página tal como 
esta se mostraba el 4 May 2011 06:39:06 GMT. Es posible que la <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html" style="text-decoration: underline; color: rgb(0, 0, 204);">página</a> haya sufrido modificaciones durante este tiempo. <a href="http://www.google.com/intl/es/help/features_list.html#cached" style="text-decoration: underline; color: rgb(0, 0, 204);">Más información</a><br><br><div style="float:right"><a href="http://webcache.googleusercontent.com/search?q=cache:GJDSmAOcQtsJ:www.codeslinger.co.uk/pages/projects/gameboy/interupts.html+codeslinger+gameboy+interupts&amp;hl=es&amp;gl=ar&amp;strip=1" style="text-decoration: underline; color: rgb(0, 0, 204);">Versión de solo texto</a></div>
<div>Se han resaltado estos términos de búsqueda: <span style="background:#ffff66;color:black;font-weight:bold">codeslinger</span>&nbsp;<span style="background:#a0ffff;color:black;font-weight:bold">gameboy</span>&nbsp;<span style="background:#99ff99;color:black;font-weight:bold">interupts</span>&nbsp;&nbsp;</div></div></div><div style="position:relative">



<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="_Emulation Programming_">
<meta name="keywords" content="_Emulation,Chip8,Gameboy,NES,SNES,Genesis,Master,System,Mega,Drive_">
<meta name="author" content="CodeSlinger /">
<link rel="stylesheet" type="text/css" href="6%20Interupts_files/css.css" media="screen,projection" title="CodeSlinger (screen)">
<link rel="stylesheet" type="text/css" href="6%20Interupts_files/print.css" media="print">
<title>codeslinger.co.uk</title>



<div>
<br><br>
</div>

<div id="container">
<div id="logo">
<h1><a href="http://www.codeslinger.co.uk/index.html"><b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk</a></h1>
</div>

<div id="navitabs">
<h2 class="hide">Site menu:</h2>
<a class="navitab" href="http://www.codeslinger.co.uk/index.php">Home</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/basics.html">Basics</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/zuko.html">Zuko</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/megadrive.html">Mega Drive/Genesis</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/mastersystem.html">Master System</a><span class="hide"> | </span>
<a class="activenavitab" href="http://www.codeslinger.co.uk/pages/projects/gameboy.html"><b style="color:black;background-color:#a0ffff">Gameboy</b></a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/chip8.html">Chip8</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/blog/index.html">Blog</a><span class="hide"> | </span>
</div>
	
<div id="desc">
<h2><b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk</h2>
<p> <b style="color:black;background-color:#a0ffff">Gameboy</b> - <b style="color:black;background-color:#99ff99">Interupts</b>.</p>

</div>

<div id="main">

<h3><b><b style="color:black;background-color:#99ff99">Interupts</b>:</b></h3>
<p>

As the chip8 system didnt have any <b style="color:black;background-color:#99ff99">interupts</b>
 I'll explain what they are and what their purpose is. An interupt is 
usually a hardware signal which tells the CPU that something special has
 happened. The CPU will check its settings
to see if it can respond to that interupt. The way the CPU responds to 
the interupt is by saving its current program counter onto the stack and
 then jumping to the interupt service routine address for the 
appropriate interupt.
It will then carry on servicing this <b style="color:black;background-color:#99ff99">interupts</b>
 routine until it has finished where it will then reload the old program
 counter and carry on executing the code from where it was before it was
 interupted. Hence the name interupt.<br><br>

There are two special registers to do with the state of interupt handling in the <b style="color:black;background-color:#a0ffff">gameboy</b>.
 The first is the Interupt Enabled register (aka IE) located at memory 
addres 0xFFFF. This is written to by the game to enable and disable
specific <b style="color:black;background-color:#99ff99">interupts</b>. For example some event may happen that would trigger an interupt like the <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/timers.html">timer</a>
 overflows, but this interupt would only get serviced if its 
corresponding bit is enabled in the
Interupt Enabled Register (aka IE). If it is enabled then the interupt 
would be serviced but if it is not enabled the interupt would sit 
pending until it becomes enabled or the game resets its request. The 
second interupt
register is the Interupt Request Register (aka IF) located at memory 
address 0xFF0F. Using the timer interupt as an example again, whenever 
the timer overflows it requests its interupt by setting its 
corresponding bit in the
Interupt Request Register where it will stay set until servicing of the 
interupt begins or the game resets it. <br><br>The final point you need to know about interupt handling is the master interupt enabled switch. This is not part
of game memory and is just a bool that the game sets on and off. When this bool is set to false no <b style="color:black;background-color:#99ff99">interupts</b> will get serviced. Below is the criteria needed to handle an interupt:

</p><p class="block">
1. When an event occurs that needs to trigger its interupt it must make an interupt request by setting its corresponding
bit in the Interupt Request Register (0xFF0F).<br><br>

2. An interupt can only be serviced if the Interupt Master Enable switch is set to true<br><br>

3. If the above two conditions are true and their is no other interupt 
with a higher priority awaiting to be serviced then it checks
the Interupt Enabled Register(0xFFFF) to see if its corresponding 
interupt bit is set to 1 to allow servicing of this particular interupt.
</p>

Step 1 gets set to true and false by the EI and DI cpu instructions 
respectively. If either step 2 or 3 is false then the interupt continues
 to wait until both 2 and 3 are true and the game hasnt turned the 
interupt request off
by resetting its corresponding interupt bit the Interupt Request 
Register(0xFF0F). 

<p></p>

<h3><b><b style="color:black;background-color:#a0ffff">Gameboy</b> <b style="color:black;background-color:#99ff99">Interupts</b>:</b> </h3>
<p>

I have mentioned a few times that an interupt has its corresponding bit 
in the Interupt Enabled Register and Interupt Request Register. I have 
also mentioned
that there are 4 <b style="color:black;background-color:#a0ffff">Gameboy</b> <b style="color:black;background-color:#99ff99">interupts</b> we will be emulating. Below is the list of <b style="color:black;background-color:#99ff99">interupts</b> and their corresponding bit in the interupt request register and interupt enabled register.

</p><p class="block">

Bit 0: V-Blank Interupt<br>
Bit 1: LCD Interupt<br>
Bit 2: Timer Interupt<br>
Bit 4: Joypad Interupt

</p>

This is also the priority listing of the <b style="color:black;background-color:#99ff99">interupts</b>.
 The lower the bit the higher priority that interupt has, so V-Blank has
 the highest priority meaning
if this interupt and another interupt are both requested in the Interupt
 Request Register then V-Blank will be serviced first. Now for an 
explanation of the <b style="color:black;background-color:#99ff99">interupts</b>:
<br><br>

<strong>V-BLANK:</strong> The <b style="color:black;background-color:#a0ffff">gameboy</b>
 draws the display a scanline at a time. There are 144 scanlines on the 
display and when it has drawn the last one
it starts again from the beginning. The time it takes to stop drawing 
scanline 144 and starting again at scanline 0 is the Vertical Blank 
period and this is when
it requests the v-blank interupt. This is the most important interupt to
 emulate correctly because during V-Blank the game can read from memory 
that was previously
restricted, mainly video memory. As stated previously the <b style="color:black;background-color:#a0ffff">gameboy</b> has a vertical refresh rate of 60 frames per second meaning that if Step 2 and Step 3 of the above
steps is always true then there should be 60 V-Blank <b style="color:black;background-color:#99ff99">interupts</b> a second. You will want to monitor this to make sure you are accurately emulating V-Blank.<br><br>

<strong>LCD:</strong> There are many reasons why the LCD would request 
an interupt and these will be looked at in more detail in the next 
chapter called <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/lcd.html">LCD</a>.
The main info you need to know about the LCD interupt is it lets the 
game know what state the LCD is in because depending what state its in 
certain memory regions become restricted.
The game can also set up a conincidence variable which means "let me 
know when you're active scanline is X". One of the things that stumped 
me with the LCD interupt
is that it can request an LCD interupt whenever V-Blank happens. I didnt
 understand why there were two v-blank <b style="color:black;background-color:#99ff99">interupts</b>, the main one which was discussed above and the one nested
into the LCD interupt. What you need to remember is that during V-Blank if the game is allowing it there will be two V-Blank <b style="color:black;background-color:#99ff99">interupts</b> requested. The first is the main V-Blank interupt
and the second is the LCD interupt. However the first vblank interupt will have the higher priority.<br><br>

<strong>TIMER:</strong> This interupt has been discussed previously in the <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/timers.html">timers</a> section. Basically the <b style="color:black;background-color:#a0ffff">gameboy</b> timer counts up at a dynamic frequency
and when it gets to value 255 and is about to overflow it lets the game know by requesting the timer interupt.<br><br>

<strong>JOYPAD:</strong> The joypad will be discussed later on in the chapter <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html">Joypad</a>. This interupt is requested whenever one of the buttons goes from the unpressed
state to the pressed state.

<p></p>

<h3><b>Requesting an Interupt:</b> </h3>
<p>

Throughout the <b style="color:black;background-color:#a0ffff">gameboy</b>
 part of this site you will see me use the function RequestInterupt. I 
call this whenever an event happens that needs to request an interupt 
and I pass
it the interupt identifier bit (see table above) of the interupt I wish 
to request. This is how the implementation of this function looks:

</p><p class="code">
void Emulator::RequestInterupt(int id)<br>
{<br>
&nbsp;&nbsp; BYTE req = ReadMemory(0xFF0F) ; <br>
&nbsp;&nbsp; req = BitSet(req,id) ;<br>
&nbsp;&nbsp; WriteMemory(0xFF0F,id) ; <br>
}
</p>

<p></p>
 
<h3><b>Checking the <b style="color:black;background-color:#99ff99">Interupts</b>:</b> </h3>
<p>

Now we know under what circumstances and interupt is requested we must also know how to handle it. If you look back to the <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/beginning.html">Getting Started</a>
 chapter you will
see the main emulator update loop. Notice how after ever opcode there is
 a function called DoInterupts? This function works by firstly checking 
if the master interupt switch is set
to true. If it is then it checks to see if there are any pending <b style="color:black;background-color:#99ff99">interupts</b> in the Interupt Request Flag. If there is then it checks all the <b style="color:black;background-color:#99ff99">interupts</b>
 in their priority order to see
if it being requested. If it is being requested it checks to see if this
 particular interupt is enabled in the Interupt Enabled register and if 
so it services it, if not it carries on checking
the lower priority <b style="color:black;background-color:#99ff99">interupts</b>.

</p><p class="code">

void Emulator::DoInterupts( )<br>
{<br>
&nbsp;&nbsp; if (m_InteruptMaster == true)<br>
&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp; BYTE req = ReadMemory(0xFF0F) ;<br>
&nbsp;&nbsp;&nbsp;&nbsp; BYTE enabled = ReadMemory(0xFFFF) ; <br>
&nbsp;&nbsp;&nbsp;&nbsp; if (req &gt; 0)<br>
&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0 ; i &lt; 5; i++) <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (TestBit(req,i) == true)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (TestBit(enabled,i))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServiceInterupt(i) ; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp; } <br>
&nbsp;&nbsp; } <br>
}

</p>

<p></p>

<h3><b>Servicing the <b style="color:black;background-color:#99ff99">Interupts</b>:</b> </h3>
<p>

Now we have detected that an interupt is to be serviced what happens 
then? Firstly the master interupt enabled switch gets set to false and 
its
corresponding bit in the Interupt Request Register is now unset. Each 
interupt has a specific interupt service routine in game memory which 
the program
counter gets set to and continues execution from there. When the 
interupt has finished servicing the program counter gets restored to 
where it currently
was and game exection continues.  The following is the location of the 
Interupt Service Routine for each of the 4 <b style="color:black;background-color:#99ff99">interupts</b>.

</p><p class="block">

V-Blank: 0x40<br>
LCD: 0x48<br>
TIMER: 0x50<br>
JOYPAD: 0x60
</p>

With this new knowledge we can write the ServiceInterupt function like so:

<p class="code">

void Emulator::ServiceInterupt(int interupt)<br>
{<br>
&nbsp;&nbsp; m_InteruptMaster = false <br>
&nbsp;&nbsp; BYTE req = ReadMemory(0xFF0F) ;<br>
&nbsp;&nbsp; req = BitReset(req,interupt) ; <br>
&nbsp;&nbsp; WriteMemory(0xFF0F,req) ;<br><br>

&nbsp;&nbsp; /// we must save the current execution address by pushing it onto the stack<br>
&nbsp;&nbsp; PushWordOntoStack(m_ProgramCounter); <br><br>

&nbsp;&nbsp; switch (interupt)<br>
&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp; case 0: m_ProgramCounter = 0x40 ; break ; <br>
&nbsp;&nbsp;&nbsp;&nbsp; case 1: m_ProgramCounter = 0x48 ; break ; <br>
&nbsp;&nbsp;&nbsp;&nbsp; case 2: m_ProgramCounter = 0x50 ; break ; <br>
&nbsp;&nbsp;&nbsp;&nbsp; case 4: m_ProgramCounter = 0x60 ; break ; <br>
&nbsp;&nbsp; }<br>
}

</p>

<h3><b>Nested <b style="color:black;background-color:#99ff99">Interupts</b>:</b> </h3>
<p>

I put this section in here because it is important to know about but it 
is not something you need to emulate. It is possible that
during the servicing of one of the <b style="color:black;background-color:#99ff99">interupts</b>
 that the interupt re-enables the master interupt switch. By doing this 
the current interupt
can get interupted itself by another interupt and will carry on 
finishing its own interupt when the new interupt finishes servicing. If 
you
have emulated your <b style="color:black;background-color:#99ff99">interupts</b> the same way I have then this functionality will automatically work but it is useful to know incase you look
in your debug logs and see it is servicing one interupt before it finishes servicing another. 

<br><br>
</p>

</div>

<div id="sidebar">
<h3><b style="color:black;background-color:#a0ffff">Gameboy</b> Emulation:</h3>

<p>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/beginning.html">Getting Started</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/hardware.html">The Hardware</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/memory.html">Memory Control and Map</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/banking.html">ROM and RAM Banking</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/timers.html">The Timers</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html"><b style="color:black;background-color:#99ff99">Interupts</b></a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/lcd.html">LCD</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/dma.html">DMA Transfer</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/graphics.html">Graphic Emulation</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html">Joypad Emulation</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/opcodes.html">Opcode Examples</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/finished.html">Finished Product</a><span class="hide"> | </span>

</p>

</div>
    
<div id="footer">
Copyright © 2008 <b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk
</div>

</div>




</div></body></html>